package com.stm.bi.report;


import com.stm.bi.core.util.DateUtils;
import com.stm.bi.core.util.ETLUtils;
import com.stm.bi.core.util.ReportExporterUtils;
import com.stm.bi.core.util.SqlUtils;
import com.stm.bi.dto.query.DimensionDataGroupQry;
import com.stm.bi.dto.query.GroupField;
import com.stm.bi.dto.query.ParamQry;
import com.stm.bi.dto.query.ProductStructQry;
import com.stm.bi.dto.query.ods.OdsListQry;
import com.stm.bi.dto.vo.*;
import com.stm.bi.enums.DateType;
import com.stm.bi.enums.ParamType;
import com.stm.bi.enums.ProductStructIndex;
import com.stm.bi.model.*;
import com.stm.bi.repository.dataobject.ods.OdsWarehouseDO;
import com.stm.bi.repository.ods.OdsWarehouseRepository;
import com.stm.framework.core.context.UserHolder;
import com.stm.framework.core.tookit.BeanToolkit;
import com.stm.framework.core.util.StringUtil;
import com.stm.framework.dbcp.JdbcService;
import com.stm.framework.dto.PageQuery;
import com.stm.framework.dto.Response;
import com.stm.framework.excel.ExcelDataExporter;
import com.stm.framework.excel.model.Column;
import com.stm.saas.api.ProductConfigRemoteService;
import com.stm.saas.api.ProductStyleDetailRemoteService;
import com.stm.saas.dto.query.ProductLabelListQry;
import com.stm.saas.dto.vo.ProductConfigVO;
import com.stm.saas.dto.vo.ProductLabelVO;
import com.stm.saas.enums.ProductStructType;
import com.stm.ucenter.api.DeptRemoteService;
import com.stm.ucenter.dto.query.org.DeptListQry;
import com.stm.ucenter.dto.vo.org.DeptVO;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.stm.framework.core.util.DateUtils.YYYY_MM_DD;
import static com.stm.saas.constant.IndexConstants.*;

@Component
public class ProductStructureQueryExe {

    private static final Logger log = LoggerFactory.getLogger(ProductStructureQueryExe.class);

    private static final String TOTAL_FILED_NAME = "total";
    private static final String TOTAL_SHOW_NAME = "合计";
    private static final String NAME = "name";

    @Resource
    private JdbcService jdbcService;

    @Resource
    private ProductStyleDetailRemoteService productStyleDetailRemoteService;

    @Resource
    private DeptRemoteService deptRemoteService;

    @Resource
    private ExcelDataExporter excelDataExporter;

    @Resource
    private ProductConfigRemoteService productConfigRemoteService;

    @Resource
    protected OdsWarehouseRepository odsWarehouseRepository;

    public Response<DatatablePage> exeTableQuery(ProductStructQry reportQry) {

        // 参数整理
        ProductStructureParam param = new ProductStructureParam(reportQry.getProductStructType(), reportQry.getProductStructIndex(), reportQry.getDateType());
        // 获取日期列表
        List<String> dateList = this.getDateList(reportQry.getStartDate(), reportQry.getEndDate(), reportQry.getDateType().getValue());
        // 获取销售类型
        String salesType = getSalesType();

        // 合计查询
        DimensionDataGroupQry qry = new DimensionDataGroupQry()
                .setOrgNo(UserHolder.getLoginUser().getOrgNo())
                .setDeptId(reportQry.getDeptId())
                .setDateType(reportQry.getDateType().getValue())
                .setStartDate(dateList.get(0))
                .setEndDate(dateList.get(dateList.size() - 1))
                .setGroupFields(param.getGroupFields())
                .setOrderBy(DATE_FIELD_NAME)
                .setGroupBy(param.getGroupBy())
                .setSalesType(salesType);

        String seasonParam = reportQry.getParams().stream().filter(item -> ParamType.SEASON.getValue().equals(item.getType())).findFirst().map(ParamQry::getCode).orElse(null);
        String parentCode = reportQry.getParams().stream().filter(item -> ParamType.PARENT_CODE.getValue().equals(item.getType())).findFirst().map(ParamQry::getCode).orElse(null);

        ProductLabelListQry productLabelListQry = new ProductLabelListQry().setProductStructType(reportQry.getProductStructType())
                .setSeason(seasonParam);

        if (ProductStructType.COLOR.getValue().equals(reportQry.getProductStructType())) {
            productLabelListQry.setParentCode(parentCode);
        } else {
            if (StringUtil.isNotEmpty(parentCode)) {
                try {
                    productLabelListQry.setParentId(Long.parseLong(parentCode));
                } catch (Exception e) {
                    return Response.failure("parentCode非Long格式");
                }
            }
        }

        Response<List<ProductLabelVO>> res = productStyleDetailRemoteService.selectLabels(productLabelListQry);
        if (!res.isSuccess()) {
            return Response.failure("RPC请求子集数据失败");
        }
        List<ProductLabelVO> productLabelList = res.get();

        List<Map> dataList = null;
        if (StringUtil.isNotEmpty(seasonParam) || StringUtil.isNotEmpty(parentCode)) {

            if (ProductStructType.COLOR.getValue().equals(reportQry.getProductStructType()) || ProductStructType.STYLE.getValue().equals(reportQry.getProductStructType())) {
                param.getCodes().addAll(productLabelList.stream().map(ProductLabelVO::getCode).toList());
            } else {
                param.getCodes().addAll(productLabelList.stream().map(ProductLabelVO::getId).map(Object::toString).toList());
            }

            // 特殊过滤条件
            if (!param.getCodes().isEmpty()) {
                param.getOtherConditions().put(param.getBusinessField(), param.getCodes());
            } else {
                dataList = new ArrayList<>();
            }
        }
        Map<String, ProductLabelVO> productCodeMap = new HashMap<>();
        if (ProductStructType.COLOR.getValue().equals(reportQry.getProductStructType()) || ProductStructType.STYLE.getValue().equals(reportQry.getProductStructType())) {
            productLabelList.forEach(item -> productCodeMap.put(item.getCode(), item));
        } else {
            productLabelList.forEach(item -> productCodeMap.put(item.getId().toString(), item));
        }

        qry.setOtherConditions(param.getOtherConditions());

        if (dataList == null) {
            if (ProductStructureParam.categoryList.contains(reportQry.getProductStructType())) {
                dataList = jdbcService.selectList(SqlUtils.buildSql(qry, "ads_res_policy_sales"), new Object[]{});
            } else {
                dataList = jdbcService.selectList(SqlUtils.buildSql(qry, "ads_base_product_multi_sales"), new Object[]{});
            }
        }

        DatatablePage datatablePage = new DatatablePage();
        List<Title> titleList = new ArrayList<>();
        titleList.add(new Title().setName(param.getTypeName() + "名称").setCode(NAME));


        dateList.forEach(item -> {
            if (DateType.MONTH.equals(reportQry.getDateType())) {
                titleList.add(new Title().setName(('0' == item.charAt(5) ? item.substring(6) : item.substring(5)) + "月").setCode(item));
            } else if (DateType.WEEK.equals(reportQry.getDateType())) {
                titleList.add(new Title().setName(DateUtils.getWeekFullColumnByDate(item)).setCode(item));
            } else if (DateType.DAY.equals(reportQry.getDateType())) {
                titleList.add(new Title().setName(item.substring(5)).setCode(item));
            } else {
                titleList.add(new Title().setName(item).setCode(item));
            }
        });
        titleList.add(new Title().setName(param.getTotalName()).setCode(TOTAL_FILED_NAME));
        if (!ProductStructType.COLOR.getValue().equals(reportQry.getProductStructType())) {
            titleList.add(new Title().setName("操作").setCode("operate"));
        }

        datatablePage.setTitles(titleList);
        datatablePage.setSize(reportQry.getPageSize());
        datatablePage.setCurrent(reportQry.getPageNum());

        // 补全前面空缺的周
        if (dataList == null && param.getNeedCumulative()) {
            this.cumulativeDataList(param, qry, dateList, dataList);
        }

        ProductChartHandle productChartHandle;
        if (ProductStructIndex.DIGESTIBILITY.equals(reportQry.getProductStructIndex())) {
            productChartHandle = new ProductChartHandle<>(DigestibilityData.class);
            this.handleDigestibility(dataList, param, qry, dateList);
        } else if (ProductStructIndex.RETURN_RATE.equals(reportQry.getProductStructIndex())) {
            productChartHandle = new ProductChartHandle<>(ReturnRateData.class);
            this.handleReturnRate(dataList, param, dateList);
        } else if (ProductStructIndex.SALES_AMOUNT.equals(reportQry.getProductStructIndex())) {
            // 销量，不需要处理
            productChartHandle = new ProductChartHandle<>(BaseOriginData.class);
            this.handleSaleAmount(dataList, param, dateList);
        } else {
            // 退货量，需取反
            productChartHandle = new ProductChartHandle<>(BaseOriginData.class);
            this.handleReturnAmount(dataList, param, dateList);
        }
        List<Map<String, String>> datas = productChartHandle.handleTableData(dataList, param, dateList);

        datas.forEach(data -> {
            if (productCodeMap.containsKey(data.get(BUSINESS_ID_FIELD_NAME))) {
                data.put("showDetail", "true");
            } else {
                data.put("showDetail", "false");
            }
        });

        datatablePage.setTotal(datas.size());
        if (reportQry.getOffset() < datas.size()) {
            // 颜色修改结构
            if (ProductStructType.COLOR.getValue().equals(reportQry.getProductStructType())) {
                Map<String, Map<String, String>> colorMap = productChartHandle.handleColorData(dataList, param, dateList);
                this.handleColorChart(datas, colorMap, datatablePage, productCodeMap, reportQry);
            } else {
                datatablePage.setDatas(datas.subList(reportQry.getOffset(), Math.min(reportQry.getOffset() + reportQry.getPageSize(), datas.size())));
            }
        } else {
            datatablePage.setDatas(new ArrayList<>());
        }
        return Response.of(datatablePage);
    }

    private List<String> getDateList(String startDate, String endDate, String dateType) {
        List<String> dateList = ETLUtils.getDateList(startDate, endDate, dateType);

        // 限制查询未来时间
        String today = com.stm.framework.core.util.DateUtils.parseDateToStr(com.stm.framework.core.util.DateUtils.addDays(new Date(), -2), YYYY_MM_DD);
        String dateStr;
        if (DateType.WEEK.getValue().equals(dateType)) {
            dateStr = DateUtils.getWeek(today);
        } else if (DateType.MONTH.getValue().equals(dateType)) {
            dateStr = today.substring(0, 7);
        } else {
            dateStr = today;
        }
        if (dateList.contains(dateStr)) {
            dateList = dateList.subList(0, dateList.indexOf(dateStr) + 1);
        }
        return dateList;
    }

    /**
     * 累计补全前面几周/天
     *
     * @param param
     * @param qry
     * @param dateList
     * @param dataList
     */
    private boolean cumulativeDataList(ProductStructureParam param, DimensionDataGroupQry qry, List<String> dateList, List<Map> dataList) {
        boolean isAdd = Boolean.FALSE;

        String firstDate = qry.getStartDate().substring(0, 4) + "-01-01";
        String startDate = qry.getStartDate();
        if (qry.getStartDate().length() == 7) {
            startDate = startDate + "-01";
        } else if (qry.getStartDate().length() == 4) {
            startDate = qry.getStartDate() + "-01-01";
        }
        // 非第一周，补全前面几周/天
        if (!startDate.equals(firstDate)) {
            if (DateType.WEEK.equals(param.getDateType())) {
                dateList.add(0, firstDate);
                isAdd = Boolean.TRUE;
                String lastDate;
                if (DateType.WEEK.equals(param.getDateType())) {
                    lastDate = DateUtils.getLastWeek(startDate, 1, 1);
                } else if (DateType.DAY.equals(param.getDateType())) {
                    lastDate = DateUtils.getLastDay(startDate);
                } else {
                    lastDate = DateUtils.getLastMonth(startDate);
                }
                List<Map> beforeQty = this.getBeforeData(qry, firstDate, lastDate, param.getProductStructType());
                for (Map item : beforeQty) {
                    item.put(DATE_FIELD_NAME, firstDate);
                    dataList.add(0, item);
                }
            }
        }

        return isAdd;
    }

    private void handleColorChart(List<Map<String, String>> dataSizeList, Map<String, Map<String, String>> colorMap, DatatablePage datatablePage, Map<String, ProductLabelVO> productCodeMap, ProductStructQry reportQry) {
        // 存在的business
        Map<String, Map> businessIdMap = dataSizeList.stream().collect(Collectors.toMap(item -> item.get(BUSINESS_ID_FIELD_NAME), item -> item));

        Map<String, String> treeParent = new HashMap<>();

        // 补充实绩查询缺少的数据
        productCodeMap.forEach((code, productLabel) -> {
            String colorCode = StringUtil.isNotEmpty(productLabel.getColorCode()) ? productLabel.getColorCode() : productLabel.getCode();

            // 颜色补数
            if (!colorMap.containsKey(colorCode)) {
                colorMap.put(colorCode, new LinkedHashMap<>());
            } else {
                Map<String, String> colorDetailMap = colorMap.get(colorCode);
                colorDetailMap.put(NAME, StringUtil.isNotEmpty(productLabel.getColorName()) ? productLabel.getColorName() : StringUtil.isNotEmpty(productLabel.getName()) ? productLabel.getName() : code);
            }

            treeParent.put(code, colorCode);
            if (businessIdMap.containsKey(code)) {
                // 把商品名称改为尺码
                Map<String, Object> map = businessIdMap.get(code);
                if (map.containsKey(NAME)) {
                    map.put(NAME, StringUtil.isNotEmpty(productLabel.getMeasuresName()) ? productLabel.getMeasuresName() : StringUtil.isNotEmpty(productLabel.getName()) ? productLabel.getName() : code);
                }
                return;
            }

            Map<String, String> colorRow = colorMap.get(colorCode);
            colorRow.put(BUSINESS_ID_FIELD_NAME, colorCode);
            colorRow.put(NAME, StringUtil.isNotEmpty(productLabel.getColorName()) ? productLabel.getColorName() : StringUtil.isNotEmpty(productLabel.getName()) ? productLabel.getName() : colorCode);

            // 数据库补数
            Map<String, String> row = new LinkedHashMap<>();
            row.put(BUSINESS_ID_FIELD_NAME, code);
            row.put(NAME, StringUtil.isNotEmpty(productLabel.getMeasuresName()) ? productLabel.getMeasuresName() : StringUtil.isNotEmpty(productLabel.getName()) ? productLabel.getName() : code);
            dataSizeList.add(row);
        });


        List<Map<String, String>> sortList = new ArrayList<>(colorMap.values());
        sortList.add(0, dataSizeList.get(0));
        List<Map<String, String>> resultList = sortList.subList(reportQry.getOffset(), Math.min(reportQry.getOffset() + reportQry.getPageSize(), sortList.size()));
        Map<String, List<Map<String, String>>> businessList = dataSizeList.stream().collect(Collectors.groupingBy(item ->
                treeParent.containsKey(item.get(BUSINESS_ID_FIELD_NAME)) ? treeParent.get(item.get(BUSINESS_ID_FIELD_NAME)) : item.get(BUSINESS_ID_FIELD_NAME)));
        List<RowData> treeData = new ArrayList<>();
        resultList.forEach(item -> {
            RowData dataItemVO = new RowData();
            dataItemVO.putAll(item);

            List<Map<String, String>> childrenList = businessList.getOrDefault(item.get(BUSINESS_ID_FIELD_NAME), new ArrayList<>());
            List<RowData> childDataList = new ArrayList<>();
            childrenList.stream().filter(child -> !TOTAL_FILED_NAME.equals(child.get(BUSINESS_ID_FIELD_NAME))).forEach(child -> {
                RowData dataChild = new RowData();
                dataChild.putAll(child);
                childDataList.add(dataChild);
            });
            dataItemVO.setChildren(childDataList);
            treeData.add(dataItemVO);
        });
        datatablePage.setDatas(treeData);
        datatablePage.setTotal(sortList.size());
    }


    private void handleReturnRate(List<Map> dataList, ProductStructureParam param, List<String> dateList) {
        // 取反
        for (Map map : dataList) {
            if (map.get(ProductStructureParam.RETURN_QTY_FIELD_NAME) != null) {
                map.put(ProductStructureParam.RETURN_QTY_FIELD_NAME, BigDecimal.ZERO.subtract((BigDecimal) map.get(ProductStructureParam.RETURN_QTY_FIELD_NAME)));
            }
        }
    }


    private void handleSaleAmount(List<Map> dataList, ProductStructureParam param, List<String> dateList) {
        // 补数
        for (Map map : dataList) {
            map.put("fieldValue1", map.get(param.getFieldName()));
        }
    }

    private void handleReturnAmount(List<Map> dataList, ProductStructureParam param, List<String> dateList) {
        // 取反
        for (Map map : dataList) {
            if (map.get(param.getFieldName()) != null) {
                map.put("fieldValue1", BigDecimal.ZERO.subtract((BigDecimal) map.get(param.getFieldName())));
            } else {
                map.put("fieldValue1", null);
            }
        }
    }

    private void handleDigestibility(List<Map> dataList, ProductStructureParam param, DimensionDataGroupQry qry, List<String> dateList) {
        // 售罄率查询补充
        this.getInventory(qry, dataList, param, dateList);
    }

    /**
     * 从年初到当前月的上个周期之间的数据
     *
     * @param qry
     * @param firstDate
     * @param lastDate
     * @return
     */
    public List<Map> getBeforeData(DimensionDataGroupQry qry, String firstDate, String lastDate, String productStructType) {
        // 查询前几月的数据
        DimensionDataGroupQry qtyQry = BeanToolkit.instance().copy(qry, DimensionDataGroupQry.class);
        qtyQry.setStartDate(firstDate)
                .setEndDate(lastDate);

        // 不需要时间分组
        qtyQry.getGroupBy().remove(DATE_FIELD_NAME);
        qtyQry.setOrderBy(null);

//        List<Map> dataList = jdbcService.selectList(SqlUtils.buildSql(qtyQry, "ads_base_product_multi_sales"), new Object[]{});
        List<Map> dataList;
        if (ProductStructureParam.categoryList.contains(productStructType)) {
            dataList = jdbcService.selectList(SqlUtils.buildSql(qry, "ads_res_policy_sales"), new Object[]{});
        } else {
            dataList = jdbcService.selectList(SqlUtils.buildSql(qry, "ads_base_product_multi_sales"), new Object[]{});
        }

        return dataList;
    }

    /**
     * 通过查询库存计算售罄率
     *
     * @param qry
     * @param qtyData
     */
    private void getInventory(DimensionDataGroupQry qry, List<Map> qtyData, ProductStructureParam param, List<String> dateList) {

        List<Map> inventoryEnd = this.selectInventoryData(qry, dateList, param.getProductStructType());

        // 整理qtyData， 出现改名情况，需处理改名后的数据
        Map<String, Map> qtyMap = new LinkedHashMap<>();
        qtyData.forEach(item -> {
            String key = item.get(DATE_FIELD_NAME) + "_" + item.get(param.getBusinessField());
            if (qtyMap.containsKey(key)) {
                Map oldMap = qtyMap.get(key);
                BigDecimal oldQty = (BigDecimal) oldMap.get(QTY_FIELD_NAME);
                oldMap.put(QTY_FIELD_NAME, oldQty.add((BigDecimal) item.get(QTY_FIELD_NAME)));
            } else {
                qtyMap.put(key, item);
            }
        });

        ;
        // 库存Map
        Map<String, Map> inventoryMap = new HashMap<>();
        inventoryEnd.forEach(item -> {
            String key = item.get(DATE_FIELD_NAME) + "_" + item.get(param.getBusinessField());
            if (inventoryMap.containsKey(key)) {
                Map oldMap = inventoryMap.get(key);
                BigDecimal oldInventory = (BigDecimal) oldMap.get(INVENTORY_FIELD_NAME);
                oldMap.put(INVENTORY_FIELD_NAME, oldInventory.add((BigDecimal) item.get(INVENTORY_FIELD_NAME)));
            } else {
                inventoryMap.put(key, item);
            }
        });

        // 把库存数据填充到qtyMap中
        qtyMap.forEach((key, map) -> {
            if (inventoryMap.containsKey(key)) {
                map.put(INVENTORY_FIELD_NAME, inventoryMap.get(key).get(INVENTORY_FIELD_NAME));
            } else {
                // 找不到找上月的
                String date = (String) map.get(DATE_FIELD_NAME);
                int index = dateList.indexOf(date);
                while (index > 0) {
                    String lastDate = dateList.get(index - 1);
                    String lastKey = lastDate + "_" + map.get(param.getBusinessField());
                    if (inventoryMap.containsKey(lastKey)) {
                        map.put(INVENTORY_FIELD_NAME, inventoryMap.get(lastKey).get(INVENTORY_FIELD_NAME));
                        break;
                    } else {
                        index--;
                    }
                }
            }
        });

        // 原始数据改为加上期末库存的数据
        List<String> keyList = qtyMap.keySet().stream().sorted().collect(Collectors.toList());
        qtyData.clear();
        for (String key : keyList) {
            qtyData.add(qtyMap.get(key));
        }
    }

    private Long getInventoryDeptId(Long deptId) {
        Map<Long, Long> deptIdMap = this.getDeptIdMap(UserHolder.getOrgId(), UserHolder.getLoginUser().getOrgNo());
        return deptIdMap.get(deptId);
    }

//    /**
//     * 特殊参数计算
//     *
//     * @param item
//     * @param fieldName
//     * @return
//     */
//    private BigDecimal getFieldValue(Map item, String fieldName) {
//
//        if (RETURN_AMOUNT_FIELD_NAME.equals(fieldName) || RETURN_RATE_FIELD_NAME.equals(fieldName)) {
//            // 总销量-销量
//            return (StringUtil.isNotEmpty(item.get(TOTAL_QTY_FIELD_NAME)) ? (BigDecimal) item.get(TOTAL_QTY_FIELD_NAME) : BigDecimal.ZERO)
//                    .subtract(StringUtil.isNotEmpty(item.get(QTY_FIELD_NAME)) ? (BigDecimal) item.get(QTY_FIELD_NAME) : BigDecimal.ZERO);
//        }
//
//        return StringUtil.isNotEmpty(item.get(fieldName)) ? (BigDecimal) item.get(fieldName) : BigDecimal.ZERO;
//
//    }


    private Map<Long, Long> getDeptIdMap(Long orgId, String orgNo) {
        //仓库与部门的对应关系逻辑
        Response<List<DeptVO>> deptResp = deptRemoteService.selectList(new DeptListQry().setOrgId(orgId));
        if (!deptResp.isSuccess()) {
            log.error("部门查询失败:{}", deptResp.getMessage());
            return new HashMap<>();
        }

        List<DeptVO> depts = deptResp.getData();
        Map<Long, Long> deptMap = new HashMap<>();
        depts.forEach(d -> deptMap.put(d.getId(), d.getParentId()));

        List<OdsWarehouseDO> warehouses = odsWarehouseRepository.selectList(new OdsListQry().setOrgNo(orgNo));
        List<Long> deptIds = warehouses.stream().map(OdsWarehouseDO::getDeptId).filter(Objects::nonNull).toList();

        //获取对应的仓库部门对应关系MAP
        return ETLUtils.getWarehouseDeptIdMap(deptMap, deptIds);
    }

    /**
     * 获取期末库存等数据
     */
    public List<Map> selectInventoryData(DimensionDataGroupQry qry, List<String> dateList, String productStructType) {

        DimensionDataGroupQry inventoryQry = BeanToolkit.instance().copy(qry, DimensionDataGroupQry.class);
        // 没有销售类型
        inventoryQry.setSalesType(null);

        Long inventoryDeptId = this.getInventoryDeptId(qry.getDeptId());
        if (inventoryDeptId == null) {
            return new ArrayList<>();
        }
        inventoryQry.setDeptId(inventoryDeptId)
                .setStartDate(dateList.getFirst())
                .setEndDate(dateList.getLast());

        List<GroupField> inventoryGroupFields = new ArrayList<>(Collections.singletonList(
                new GroupField().setFieldName(INVENTORY_FIELD_NAME).setGroupType("sum")
        ));

        inventoryQry.setGroupFields(inventoryGroupFields);

        List<Map> maps;
        if (ProductStructureParam.categoryList.contains(productStructType)) {
            maps = jdbcService.selectList(SqlUtils.buildSql(inventoryQry, "ads_res_policy_inventory"), new Object[]{});
        } else {
            maps = jdbcService.selectList(SqlUtils.buildSql(inventoryQry, "ads_base_product_inventory"), new Object[]{});
        }

        return maps;
    }

    public Response<Chart<List<List<Object>>>> exeChartQuery(ProductStructQry reportQry) {
        String code = reportQry.getParams().stream().filter(item -> ParamType.CODE.getValue().equals(item.getType())).findFirst().map(ParamQry::getCode).orElse(null);
        if (StringUtil.isEmpty(code)) {
            return Response.failure("缺少具体编码参数： code");
        }
//        Response<List<ProductLabelVO>> res = productStyleDetailRemoteService.selectLabels(
//                new ProductLabelListQry()
//                        .setProductStructType(reportQry.getProductStructType().getValue())
//                        .setCode(code));
//        if (!res.isSuccess() || res.get().isEmpty()) {
//            return Response.failure("RPC请求数据失败或没有此编码");
//        }
//        ProductLabelVO productLabel = res.get().get(0);

        ProductStructureParam param = new ProductStructureParam(reportQry.getProductStructType(), reportQry.getProductStructIndex(), reportQry.getDateType());

        // 获取日期列表
        List<String> dateList = this.getDateList(reportQry.getStartDate(), reportQry.getEndDate(), reportQry.getDateType().getValue());

        // 获取销售类型
        String salesType = getSalesType();

        // 合计查询
        DimensionDataGroupQry qry = new DimensionDataGroupQry()
                .setOrgNo(UserHolder.getLoginUser().getOrgNo())
                .setDeptId(reportQry.getDeptId())
                .setDateType(reportQry.getDateType().getValue())
                .setStartDate(dateList.get(0))
                .setEndDate(dateList.get(dateList.size() - 1))
                .setGroupFields(param.getGroupFields())
                .setOrderBy(DATE_FIELD_NAME)
                .setGroupBy(param.getGroupBy())
                .setSalesType(salesType);

        // 添加单独查询入参
        param.getOtherConditions().put(param.getBusinessField(), code);
        qry.setOtherConditions(param.getOtherConditions());

        List<Map> dataList;
        if (ProductStructureParam.categoryList.contains(reportQry.getProductStructType())) {
            dataList = jdbcService.selectList(SqlUtils.buildSql(qry, "ads_res_policy_sales"), new Object[]{});
        } else {
            dataList = jdbcService.selectList(SqlUtils.buildSql(qry, "ads_base_product_multi_sales"), new Object[]{});
        }

        boolean isAdd = false;
        // 补全前面空缺的周
        if (param.getNeedCumulative()) {
            isAdd = this.cumulativeDataList(param, qry, dateList, dataList);
        }


        ProductChartHandle productChartHandle;
        if (ProductStructIndex.DIGESTIBILITY.equals(reportQry.getProductStructIndex())) {
            productChartHandle = new ProductChartHandle<>(DigestibilityData.class);
            this.handleDigestibility(dataList, param, qry, dateList);
        } else if (ProductStructIndex.RETURN_RATE.equals(reportQry.getProductStructIndex())) {
            productChartHandle = new ProductChartHandle<>(ReturnRateData.class);
            this.handleReturnRate(dataList, param, dateList);
        } else if (ProductStructIndex.SALES_AMOUNT.equals(reportQry.getProductStructIndex())) {
            productChartHandle = new ProductChartHandle<>(BaseOriginData.class);
            this.handleSaleAmount(dataList, param, dateList);
        } else {
            productChartHandle = new ProductChartHandle<>(BaseOriginData.class);
            this.handleReturnAmount(dataList, param, dateList);
        }
        List<List<Object>> datas = productChartHandle.handleChartData(dataList, param, dateList);
        // 删除范围
        List<Object> totalData = datas.get(0);
        datas.remove(0);
        if (isAdd && !datas.isEmpty()) {
            datas.remove(0);
        }

        Chart chart = new Chart();
        chart.getItems().add(param.getProductStructIndex().getDesc());
        if (!ProductStructIndex.DIGESTIBILITY.equals(param.getProductStructIndex())
                && !ProductStructIndex.RETURN_RATE.equals(param.getProductStructIndex())) {
            chart.getItems().add(param.getTotalName());
        }

        chart.setDatas(datas);
//        chart.setName(productLabel.getName() + "推移图");
        chart.setName("推移图");
        // 合计运算
        List<List<Object>> totalList = new ArrayList<>();
        totalList.add(totalData);
        chart.setExtend(totalList);
        return Response.of(chart);
    }

    /**
     * 获取销售类型
     * @return
     */
    private String getSalesType() {
        String salesDefinition = "dealing";
        Response<ProductConfigVO> prodResp = productConfigRemoteService.selectByOrgId(UserHolder.getOrgId());
        // TODO 特殊转换（之后删除）

        if (prodResp != null && prodResp.getData() != null) {
            salesDefinition = prodResp.getData().getSalesDefinition();
        }
        if ("delivery".equals(salesDefinition)) {
            salesDefinition = "dealing";
        }
        return salesDefinition;
    }

    public Response export(HttpServletResponse response, ProductStructQry reportQry) {
        reportQry.setPageNum(1);
        reportQry.setPageSize(PageQuery.MAX_PAGE_SIZE);
        Response<DatatablePage> res = this.exeTableQuery(reportQry);
        if (!res.isSuccess()) {
            return res;
        }
        DatatablePage datatablePage = res.get();
        if (datatablePage == null || (datatablePage.getDatas() == null && datatablePage.getTitles() == null)) {
            return Response.failure("暂无可导出数据");
        }
        List<Title> title = datatablePage.getTitles();
        title.removeIf(item -> "operate".equals(item.getCode()));
        List<Map> datas = ReportExporterUtils.getExporterDataList(datatablePage);
        List<Column> columns = new ArrayList<>();
        for (Title t : title) {
            columns.add(new Column().setTitle(t.getName()).setFieldName(t.getCode()));
        }
        try {
            excelDataExporter.export(response, columns, datas, "商品结构");
        } catch (Exception e) {
            log.error("导出异常==>", e.getMessage(), e);
            return Response.failure();
        }
        return Response.success();
    }

}
